from quant_researcher.quant.project_tool.time_tool import get_yesterday, calc_date_diff, date_shifter
from quant_researcher.quant.datasource_fetch.crypto_api.coingecko import CoinGeckoAPI
from quant_researcher.quant.datasource_fetch.crypto_api.coinmarketcap import get_asset_ohlcvm_via_http
from quant_researcher.quant.datasource_fetch.crypto_api.glassnode import get_prices
from quant_researcher.quant.project_tool.file_tool import get_all_filename_path,copy_file
from quant_researcher.quant.datasource_fetch.crypto_api.self_defined import true_stalecoin_crypto
from quant_researcher.quant.project_tool.db_operator.my_excel import df_list_2_excel_sheets
import os
import pandas as pd
import numpy as np
import time


DATA_DIR = f'E:\\指标数据'



def get_all_ohlcvm_data(data_source='coingecko', asset='all', start_date=None, end_date=None, if_print=False, **kwargs):
    """

    :param data_source:
    :param asset: 获取所有的，还是某个资产的
    :param end_date:
    :param if_print:
    :param kwargs: 关键字参数
        - initialize：所有数据重新获取，还是在原有的数据上
        - gap_days: 默认更新到最新多少天内
    :return:
    """

    initialize = kwargs.pop('initialize', False)
    gap_days = kwargs.pop('gap_days', 2)

    if start_date is None:
        start_date = '2013-01-01'
    if end_date is None:
        end_date = get_yesterday(marker='with_n_dash')  # 计算截止昨日收盘

    if data_source == 'coingecko':
       pass

    elif data_source == 'coinmarketcap':
        if asset == 'all':
            pass

        else:
            file_path = os.path.join(DATA_DIR, r'all_history_ohlcvm_coinmarketcap\all_history_ohlcvm_coinmarketcap')
            file_name = os.path.join(file_path, f'{asset}')


            history_ohlcvm = pd.read_excel(f'{file_name}.xlsx', index_col='end_date')
            if history_ohlcvm.empty:
                history_ohlcvm_latest_date = '2013-01-01'
            else:
                history_ohlcvm_latest_date = history_ohlcvm.index[-1]

            all_ohlcvm = get_asset_ohlcvm_via_http(asset=asset, range='1Y')
            # 数据合并
            next_date = date_shifter(history_ohlcvm_latest_date, step='days', how_many=1)
            if all_ohlcvm.index[0] > next_date:
                print(f'读取的最新数据跟历史数据接不上，请检查数据源是否有问题')
                raise ValueError
            asset_df = pd.concat([history_ohlcvm, all_ohlcvm.loc[next_date:, ]])
            asset_df = asset_df[history_ohlcvm.columns]
            asset_df.sort_index(inplace=True)
            asset_df.index.name = 'end_date'

            try:
                # ohlc的数据还是以glassnode的数据为准
                file_path_1 = os.path.join(DATA_DIR, 'all_history_ohlcvm_coinmarketcap')
                file_name_1 = os.path.join(file_path_1, f'all_coin_list_coinmarketcap')
                all_coin_list_df = pd.read_excel(f'{file_name_1}.xlsx', index_col='slug')
                symbol = all_coin_list_df.loc[asset, 'symbol']
                prices_df = get_prices(ohlc=True, asset=f'{symbol}', start_date=start_date, end_date=end_date)
            except Exception as err:  # ohlc 数据获取失败
                prices_df = pd.DataFrame(np.NAN, columns=['open', 'high', 'low', 'close'], index=asset_df.index)

            all_df = pd.concat([asset_df[['market_cap', 'amount', 'volume']], prices_df], axis=1)
            # all_df.dropna(axis=0, inplace=True)
            all_df.sort_index(ascending=True, inplace=True)
            all_df.index.name = 'end_date'

            if if_print:
                file_name = os.path.join(DATA_DIR, f'{symbol}_history_ohlcvm')
                all_df.to_excel(f'{file_name}.xlsx')
            return all_df


def get_stablecoin_marketcap_data(data_source='coinmarketcap', update=True, start_date=None, end_date=None,
                                  if_print=False):
    """

    :param data_source:
    :param end_date:
    :param if_print:
    :return:
    """

    if start_date is None:
        start_date = '2013-01-01'
    if end_date is None:
        end_date = get_yesterday(marker='with_n_dash')  # 计算截止昨日收盘

    file_path = os.path.join(DATA_DIR, f'all_history_ohlcvm_{data_source}')
    file_name = os.path.join(file_path, f'stablecoin_{data_source}')
    # 文件备份
    # backup_path = os.path.join(file_path, f'all_history_ohlcvm_{data_source}_backup')
    # copy_file(f'{file_name}.xlsx', backup_path)

    all_recent_data_list = []
    asset_df_list = []
    for asset in true_stalecoin_crypto.keys():
        if update:
            asset_history_data = pd.read_excel(f'{file_name}.xlsx', sheet_name=asset)
            asset_history_data['end_date'] = pd.to_datetime(asset_history_data['end_date'])
            asset_history_data['end_date'] = asset_history_data['end_date'].dt.strftime('%Y-%m-%d')
            asset_history_data.set_index('end_date', inplace=True)

            if data_source == 'coinmarketcap':
                recent_data = get_asset_ohlcvm_via_http(asset=true_stalecoin_crypto[asset], range='1Y')
            elif data_source == 'coingecko':
                start_date = date_shifter(end_date, step='days', how_many=-91)
                recent_data = get_all_ohlcvm_data(data_source='coingecko', asset=asset, start_date=start_date,
                                                  end_date=None, if_print=False)

            next_date = date_shifter(asset_history_data.index[-1], step='days', how_many=1)
            if recent_data is not None:
                asset_df = pd.concat([asset_history_data.iloc[:, ], recent_data.loc[next_date:, ]])
            else:
                asset_df = asset_history_data.copy()
                recent_data = asset_history_data.copy()

            asset_df = pd.concat([asset_history_data.iloc[:, ], recent_data.loc[next_date:, ]])
            asset_df = asset_df[asset_history_data.columns]
            asset_df.sort_index(inplace=True)
            asset_df.index.name = 'end_date'

        else:  # 重算全部历史数据
            if data_source == 'coingecko':
                recent_data = get_all_ohlcvm_data(data_source='coingecko', asset=asset, start_date=start_date,
                                                  end_date=None, if_print=False)
            else:
                raise NotImplementedError
            asset_df = recent_data.copy()

        recent_data.rename(columns={'market_cap': asset}, inplace=True)
        all_recent_data_list.append(recent_data[asset])
        asset_df_list.append(asset_df)
        time.sleep(5)  # 避免读取太频繁

    all_recent_data_df = pd.concat(all_recent_data_list, axis=1)
    all_recent_data_df['stablecoin_market_cap'] = all_recent_data_df.sum(axis=1)
    if update:
        history_data = pd.read_excel(f'{file_name}.xlsx', sheet_name='stablecoin_marketcap')
        history_data['end_date'] = pd.to_datetime(history_data['end_date'])
        history_data['end_date'] = history_data['end_date'].dt.strftime('%Y-%m-%d')
        history_data.set_index('end_date', inplace=True)
        all_df = pd.concat([history_data.iloc[:-1, ], all_recent_data_df.loc[history_data.index[-1]:, ]])
    else:
        all_df = all_recent_data_df.copy()

    all_df.sort_index(inplace=True)
    all_df.index.name = 'end_date'

    asset_df_list.append(all_df)
    if if_print:
        sheet_name_list = list(true_stalecoin_crypto.keys())
        sheet_name_list.append(f'stablecoin_marketcap')
        df_list_2_excel_sheets(df_list=asset_df_list, res_dir=file_path, file_name=f'stablecoin_{data_source}',
                               sheet_name_list=sheet_name_list, index=True)

    return asset_df_list


if __name__ == '__main__':
    # get_all_ohlcvm_data(data_source='coinmarketcap', asset='bitcoin', start_date=None, end_date=None, if_print=True)
    # get_all_ohlcvm_data(data_source='coinmarketcap', asset='ethereum', start_date=None, end_date=None, if_print=True)

    # 获取稳定币市值数据
    get_stablecoin_marketcap_data(data_source='coinmarketcap', update=True, start_date=None, end_date=None, if_print=True)

